package com.wind.utils.cipher;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import javax.crypto.Cipher;

/**
 * <p>
 *     RSA
 * </p>
 * @author wind
 * @date    2024-12-11 10:38
 * @version v1.0
 */
public class RsaUtil {

    // 加密算法
    public static final String KEY_ALGORITHM = "RSA";

    /**
     * 生成密钥对,list列表，第一个元素为公钥，第二个元素为私钥
     * @return
     * @throws Exception
     */
    public static List<String> genKeyPair() throws Exception {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        keyPairGen.initialize(2048, SecureRandom.getInstanceStrong());
        KeyPair keyPair = keyPairGen.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        // 将公钥和私钥转换为Base64编码的字符串
        String publicKeyString = Base64.getEncoder().encodeToString(publicKey.getEncoded());
        String privateKeyString = Base64.getEncoder().encodeToString(privateKey.getEncoded());
        return Arrays.asList(publicKeyString, privateKeyString);
    }

    /**
     * 使用公钥加密
     *
     * @param str     待加密的字符串
     * @param publicKey 公钥
     * @return 加密后的字符串
     * @throws Exception 加密过程中的异常
     */
    public static String encrypt(String str, String publicKey) throws Exception {
        byte[] decoded = Base64.getDecoder().decode(publicKey);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decoded);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey keyPublic = keyFactory.generatePublic(keySpec);

        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, keyPublic);
        byte[] encryptedData = cipher.doFinal(str.getBytes());
        return Base64.getEncoder().encodeToString(encryptedData);
    }

    /**
     * 使用私钥解密
     *
     * @param str     待解密的字符串
     * @param privateKey 私钥
     * @return 解密后的字符串
     * @throws Exception 解密过程中的异常
     */
    public static String decrypt(String str, String privateKey) throws Exception {
        byte[] decoded = Base64.getDecoder().decode(privateKey);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decoded);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey keyPrivate = keyFactory.generatePrivate(keySpec);

        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, keyPrivate);
        byte[] decryptedData = cipher.doFinal(Base64.getDecoder().decode(str));
        return new String(decryptedData);
    }
}